use crate::{
    dao::{tutorials, types},
    models::{TreeNode, Tutorial, Type},
    DbPool,
};
use actix_http::http::header;
use actix_web::{error, get, web, Error, HttpResponse, Result};
use comrak::{markdown_to_html, ComrakOptions};

// store tera template in application state

#[get("/")]
pub async fn index(
    tmpl: web::Data<tera::Tera>,
    pool: web::Data<DbPool>,
) -> Result<HttpResponse, Error> {
    let mut ctx = tera::Context::new();

    let conn = pool.get().expect("couldn't get db connection from pool");
    let ret = types::get_all(false, &conn).unwrap();
    let nodes = TreeNode::<Type>::new(ret);

    // 列出所有教程
    ctx.insert("tutorials", &nodes);

    // 最新的100个教程文章
    let t100 = tutorials::get_latest(100, &conn).unwrap();
    ctx.insert("tutorial100", &t100);

    let mut menus = vec![];
    for v in &nodes[0].children {
        menus.push(v.node.clone());
    }
    // 菜单
    ctx.insert("menus", &menus);

    let s = tmpl
        .render("index.html", &ctx)
        .map_err(|_| error::ErrorInternalServerError("Template error"))?;
    Ok(HttpResponse::Ok().content_type("text/html").body(s))
}

// 根据教程编号 跳转到第一个教程
#[get("/tutorials/{id}")]
pub async fn goto_first_tutorial(
    id: web::Path<String>,
    pool: web::Data<DbPool>,
) -> Result<HttpResponse, Error> {
    let conn = pool.get().expect("couldn't get db connection from pool");
    if let Ok(t) = tutorials::get_first_by_tid(id.clone(), false, &conn) {
        return Ok(HttpResponse::Found()
            .header(header::LOCATION, format!("/tutorial/{}.html", t.id))
            .body(""));
    }
    Ok(HttpResponse::NotFound()
        .content_type("text/html")
        .body("<h1>article not found</h1>"))
}

#[get("/tutorial/{id}.html")]
pub async fn article(
    tmpl: web::Data<tera::Tera>,
    id: web::Path<String>,
    pool: web::Data<DbPool>,
) -> Result<HttpResponse, Error> {
    let conn = pool.get().expect("couldn't get db connection from pool");
    let mut ctx = tera::Context::new();
    let id = id.into_inner();
    if let Ok(mut t) = tutorials::get(id.clone(), false, &conn) {
        let mut options = ComrakOptions::default();
        options.extension.table = true;
        t.content = markdown_to_html(&t.content, &options);
        ctx.insert("tutorial", &t);

        if let Ok(ret) = tutorials::get_by_tid(t.tid.clone(), true, false, &conn) {
            let tutorials = TreeNode::<Tutorial>::new(ret.clone());
            ctx.insert("tutorials", &tutorials);
        }

        ctx.insert("title", &t.title);
        ctx.insert("keywords", &t.keyword);
        ctx.insert("description", &t.description);
        let tp = types::get(t.tid, &conn).unwrap();
        // 当前课程信息
        ctx.insert("type", &tp);
        ctx.insert("og_image", &tp.pic);
        if let Ok(ts) = types::get_all_children(tp.pid.unwrap(), false, &conn) {
            // 菜单
            ctx.insert("menus", &ts);
        }
    }

    let s = tmpl
        .render("article.html", &ctx)
        .map_err(|_| error::ErrorInternalServerError("Template error"))?;
    Ok(HttpResponse::Ok().content_type("text/html").body(s))
}
